package com.justgame.project.cloud.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.util.Date;
import java.util.Optional;

/**
 * Token工具类
 */
@Slf4j
public class TokenUtil {
    private static PrivateKey PrivateKey;
    public static final String HEADER_KEY = "Authorization";
    private static final String SECRET_KEY = "secret_key";
    private static final long EXPIRATION_TIME = 864_000_000; // 10 days

    static {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
            keyGen.initialize(2048);
            KeyPair keyPair = keyGen.generateKeyPair();
            TokenUtil.PrivateKey = keyPair.getPrivate();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Token
     */
    public static String getToken(@NonNull HttpServletRequest request) {
        return Optional.ofNullable(request.getHeader(HEADER_KEY))
                .orElse(request.getParameter(HEADER_KEY));
    }

    /**
     * token验证并返回信息
     * @param token 令牌
     */
    public static Optional<Claims> validateToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(PrivateKey)
                    .parseClaimsJws(token)
                    .getBody();
            return Optional.of(claims);
        } catch (Exception e) {
            log.error("Token验证失败", e);
            return Optional.empty();
        }
    }

    /**
     * token生成
     * @param userid 用户id
     */
    public static String generateToken(Long userid) {
        try {
            return Jwts.builder()
                    .setSubject(userid.toString())
                    .setIssuedAt(new Date())
                    .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                    .signWith(SignatureAlgorithm.RS256,PrivateKey)
                    .compact();
        } catch (Exception e) {
            log.error("生成Token失败" + e);
        }
        return null;
    }

}
